﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Linq;

namespace SStuff.FlowControls
{
    public static class Extensions
    {
        public static IObservable<Event<EventArgs>> GetLoaded(this FrameworkElement source)
        {
            return Observable.FromEvent<RoutedEventHandler, EventArgs>(
                handler => (s, a) => handler(s, a),
                handler => source.Loaded += handler,
                handler => source.Loaded -= handler);
        }

        public static IObservable<Event<EventArgs>> GetLayoutUpdated(this FrameworkElement source)
        {
            return Observable.FromEvent<EventHandler, EventArgs>(
                handler => (s, a) => handler(s, a),
                handler => source.LayoutUpdated += handler,
                handler => source.LayoutUpdated -= handler);

        }

        public static IObservable<Event<EventArgs>> GetUnloaded(this FrameworkElement source)
        {
            if (source.IsInMainVisualTree())
                throw new InvalidOperationException("the unloaded event must be subscribed before the element is loaded");

            return (from loaded in source.GetLoaded()
                    from layouted in (source.GetLayoutUpdated()
                                    .Where(e => !source.IsInMainVisualTree()).Take(1))
                    select layouted).Repeat();
        }
        public static bool IsInMainVisualTree(this DependencyObject source)
        {
            return source.GetVisualAncestors().Contains(Application.Current.RootVisual);
        }

        public static IEnumerable<DependencyObject> GetVisualAncestors(this DependencyObject source)
        {
            DependencyObject current = VisualTreeHelper.GetParent(source);
            while (current != null)
            {
                yield return current;
                current = VisualTreeHelper.GetParent(current);
            }
        }

    }
}
